package main

import (
	"fmt"
	"math/rand"
	"time"
)

func main() {

	//Method1()

	//解决办法就是 在外部初始化timer
	Method2()
}

func Method2() {
	t := time.NewTimer(2 * time.Second)
	datas := make(chan bool)
	go func() {
		for {
			tmp := rand.Intn(5)
			delay := time.Duration(tmp) * time.Second
			time.Sleep(delay)
			datas <- true
		}
	}()
	for {
		select {
		case <-datas:
			//注意需要每次都重置，表明每次正确收到数据后重新开始3秒超时
			func() {
				defer t.Reset(2 * time.Second)
			}()
			fmt.Println("收到数据")
		case <-t.C:
			fmt.Println("到期！")
		}
	}
}

func Method1() {
	//for-select模式中如果始终创建timer将导致内存泄露
	//一旦离开select作用域，timer将失去被引用，等待回收，但是必须等到计时结束才可以
	//因此一旦大量创建长时间才出发的timer，将很容易导致内存泄露
	datas := make(chan bool)
	go func() {
		for {
			tmp := rand.Intn(5)
			fmt.Println(tmp)
			delay := time.Duration(tmp) * time.Second
			time.Sleep(delay)
			datas <- true
		}
	}()
	for {
		select {
		case <-datas:
			fmt.Println("收到数据")
		case <-time.After(3 * time.Second): //每次select都会创建
			fmt.Println("到期！")
		}
	}
}
